package ro.savatech.pg.flightlog;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

/**
 * This class model the device memory.
 * 
 * @author Dan Corneanu
 */
public class ConfigurationMem {
	public static final short RECORD_SIZE = 0x0501;
	private static final short LAST_FLIGHT_NB = 0x00F0;
	private static final int START_FLIGHT_INDEX = 0x0100;

	private FlightIndexEntry[] indexEntries;
	private short lastFlightNb;

	private ConfigurationMem() {

	}

	public static ConfigurationMem fromRaw(byte[] rawDeviceMem) {
		if (RECORD_SIZE != rawDeviceMem.length) {
			throw new IllegalArgumentException(String.format(
					"The size of a device memory must be exactlly 0x%X.",
					RECORD_SIZE));
		}

		ConfigurationMem deviceMem = new ConfigurationMem();

		short lastFlightNb = (short) (rawDeviceMem[LAST_FLIGHT_NB] & 0xFF);

		deviceMem.lastFlightNb = lastFlightNb;
		deviceMem.indexEntries = new FlightIndexEntry[deviceMem.lastFlightNb + 1];
		for (int i = 0; i < lastFlightNb + 1; i++) {
			int from = START_FLIGHT_INDEX + i * 0x15;
			byte[] flightIndexEntryRaw = Arrays.copyOfRange(rawDeviceMem, from,
					from + 0x15);
			FlightIndexEntry flightIndex = FlightIndexEntry
					.fromRaw(flightIndexEntryRaw);
			deviceMem.indexEntries[i] = flightIndex;
		}

		return deviceMem;
	}

	public static ConfigurationMem fromStream(InputStream input) {
		try {
			DataInputStream is = new DataInputStream(input);
			byte[] raw = new byte[ConfigurationMem.RECORD_SIZE];
			is.readFully(raw);

			ConfigurationMem cfgMem = ConfigurationMem.fromRaw(raw);
			return cfgMem;
		} catch (IOException e) {
			throw new FLException("Could not read from dump file.", e);
		}
	}

	public FlightIndexEntry[] getIndexEntries() {
		return indexEntries;
	}

	@Override
	public String toString() {
		StringBuffer buff = new StringBuffer();
		for (FlightIndexEntry entry : this.indexEntries) {
			buff.append(entry);
			buff.append('\n');
		}
		return buff.toString();
	}
}
